This patch fixes a bug where raise_softirq(SCHEDULE_SOFTIRQ) is called
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 21 Sep 2005 16:58:55 +0000 (16:58 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 21 Sep 2005 16:58:55 +0000 (16:58 +0000)
upon a hlt instruction from a VMX guest, causing repeated VMExits when
the guest is idle. At the same time, it disables the monitor/mwait
feature as it's not feasible to implement for vcpu.

Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
Signed-off-by: Asit Mallick <asit.k.mallick@intel.com>
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
xen/arch/x86/vmx.c
xen/arch/x86/vmx_intercept.c
xen/include/asm-x86/vmx_virpit.h

index bb4d9cf94237dbca0693306002e6039c660c0198..c4954ee994a70605e39f6f46dcf9eef910f2516c 100644 (file)
@@ -471,6 +471,8 @@ static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs)
         }
 #endif
 
+        /* Unsupportable for virtualised CPUs. */
+        clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
     }
 
     regs->eax = (unsigned long) eax;
@@ -1461,7 +1463,7 @@ volatile unsigned long do_hlt_count;
  */
 void vmx_vmexit_do_hlt(void)
 {
-    raise_softirq(SCHEDULE_SOFTIRQ);
+    do_block();
 }
 
 static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
@@ -1511,12 +1513,6 @@ static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
     }
 }
 
-volatile unsigned long do_mwait_count;
-static inline void vmx_vmexit_do_mwait(void)
-{
-    raise_softirq(SCHEDULE_SOFTIRQ);
-}
-
 #define BUF_SIZ     256
 #define MAX_LINE    80
 char print_buf[BUF_SIZ];
@@ -1798,9 +1794,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
         __update_guest_eip(inst_len);
         break;
     case EXIT_REASON_MWAIT_INSTRUCTION:
-        __get_instruction_length(inst_len);
-        __update_guest_eip(inst_len);
-        vmx_vmexit_do_mwait();
+        __vmx_bug(&regs);
         break;
     default:
         __vmx_bug(&regs);       /* should not happen */
index 1f1494c4256ab40b56e85ff80900e2bbb70ec57e..865c51ca306b037bc39e3015e90c4f4c64413c64 100644 (file)
@@ -28,6 +28,7 @@
 #include <xen/sched.h>
 #include <asm/current.h>
 #include <io_ports.h>
+#include <xen/event.h>
 
 #ifdef CONFIG_VMX
 
@@ -205,6 +206,7 @@ static void pit_timer_fn(void *data)
     /* Set the pending intr bit, and send evtchn notification to myself. */
     if (test_and_set_bit(vpit->vector, vpit->intr_bitmap))
         vpit->pending_intr_nr++; /* already set, then count the pending intr */
+    evtchn_set_pending(vpit->v, iopacket_port(vpit->v->domain));
 
     /* pick up missed timer tick */
     if ( missed_ticks > 0 ) {
@@ -281,6 +283,7 @@ void vmx_hooks_assist(struct vcpu *d)
         }
 
         vpit->intr_bitmap = intr;
+        vpit->v = d;
 
         vpit->scheduled = NOW() + vpit->period;
         set_ac_timer(&vpit->pit_timer, vpit->scheduled);
index e2a87d26f747aec67e0c2aea3642b3a8e23294dd..1f80a83f0ea5bf0fb41b188636f5c991f8f90278 100644 (file)
@@ -35,8 +35,8 @@ struct vmx_virpit_t {
 
     unsigned int count;  /* the 16 bit channel count */
     unsigned int init_val; /* the init value for the counter */
-
-} ;
+    struct vcpu *v;
+};
 
 /* to hook the ioreq packet to get the PIT initializaiton info */
 extern void vmx_hooks_assist(struct vcpu *d);